home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SNNSV32.ZIP / SNNSv3.2 / xgui / sources / ui_inversion.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-25  |  27.6 KB  |  900 lines

  1. /*****************************************************************************
  2.   FILE           : ui_inversion.c
  3.   SHORTNAME      : inversion.c
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE  : contains all routines for handling inversion of NN, invented
  7.             by Alexander Linden
  8.  
  9.   FUNCTIONS: -- ui_inversion
  10.                Purpose : Main program for the inversion
  11.             Calls   : void ui_confirmOk();
  12.                   Widget ui_xCreateButtonItem();
  13.               int ui_set_IO_units();
  14.                          various X routines for widget handling
  15.  
  16.             -- ui_invSetup
  17.                Purpose : Display setup panel for Inversion
  18.                Calls   : Widget ui_xCreateDialogItem();
  19.                          Widget ui_xCreateLabelItem();
  20.  
  21.             -- ui_inv_popupDone
  22.                Purpose : read new params and close popup display
  23.                Calls   : nothing
  24.  
  25.             -- ui_invHelp
  26.                Purpose : display help information for inversion
  27.                Calls   : nothing
  28.  
  29.             -- ui_inv_helpDone
  30.                Purpose : close help window
  31.                Calls   : nothing
  32.  
  33.             -- ui_set_IO_units
  34.                Purpose : create a chain of input units 
  35.                Calls   : int krui_getUnitTType();
  36.                          void krui_getUnitPosition();
  37.  
  38.             -- ui_closeDisplay
  39.                Purpose : closing all widgets for inversion
  40.                Calls   : nothing
  41.  
  42.             -- ui_invNew
  43.                Purpose : restart the inversion
  44.                Calls   : void ui_drawInput();
  45.  
  46.             -- ui_invEvent
  47.                Purpose : event handler for graphic window 
  48.                Calls   : void ui_drawInput();
  49.  
  50.             -- ui_inversionFromUpdate
  51.                Purpose : refresh the screen
  52.                Calls   : void ui_drawInput();
  53.  
  54.             -- ui_drawInput
  55.                Purpose : drawing the input units
  56.                Calls   : int krui_getFirstUnit();
  57.                          void ui_col_setPalette();
  58.                          void krui_getUnitPosition();
  59.                          void ui_drawGrowingThing();
  60.                          position ui_utilPixUpperLeft();
  61.                          position ui_utilPixLowerRight();
  62.                          void ui_xDeleteRect();
  63.  
  64.             -- ui_start_inversion          
  65.                Purpose : Program to start inversion 
  66.                Calls   : X routines
  67.  
  68.             -- ui_stop_inversion          
  69.                Purpose : Program to stop inversion 
  70.                Calls   : X routines
  71.  
  72.             -- ui_do_inversion          
  73.                Purpose : Program for actual inversion algorithm
  74.                Calls   : void ui_confirmOk();
  75.                          void ui_sel_lookForItem();
  76.                          int krui_initInversion();
  77.                          void krui_inv_forwardPass();
  78.                          int krui_inv_backwardPass();
  79.                          void ui_drawInput();
  80.  
  81.  AUTHOR   : Guenter Mamier
  82.  DATE     : 28.02.92
  83.  VERSION  : 0.20
  84.  
  85.  CHANGED BY     : Sven Doering
  86.  IDENTIFICATION : @(#)ui_inversion.c    1.19 3/2/94
  87.  SCCS VERSION   : 1.19
  88.  LAST CHANGE    : 3/2/94
  89.  
  90.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  91.  
  92. ******************************************************************************/
  93.  
  94. #ifndef MASPAR_KERNEL
  95.  
  96. #include <stdio.h>            /* For the Syntax message */
  97. #include <stdlib.h>
  98. #include <math.h>
  99.  
  100. #include "ui.h"
  101.  
  102. #include <X11/Shell.h>
  103. #include <X11/cursorfont.h>
  104. #include <X11/Xaw/MenuButton.h>
  105. #include <X11/Xaw/Text.h>
  106. #include <X11/Xaw/TextSrc.h>
  107. #include <X11/Xaw/Form.h>
  108. #include <X11/Xaw/Box.h>
  109. #include <X11/Xaw/Cardinals.h>
  110. #include <X11/Xaw/Command.h>
  111. #include <X11/Xaw/Dialog.h>
  112. #include <X11/Xaw/List.h>
  113. #include <X11/Xaw/AsciiText.h>
  114. #include <X11/Xaw/Scrollbar.h>
  115. #include <X11/Xaw/Viewport.h>
  116.  
  117. #include "ui_xWidgets.h"
  118. #include "ui_main.h"
  119. #include "ui_mainP.h"
  120. #include "ui_netGraph.h"
  121. #include "ui_utilP.h"
  122. #include "ui_display.h"
  123. #include "ui_selection.h"
  124. #include "ui_color.h"
  125. #include "ui_confirmer.h"
  126. #include "ui_xGraphic.h"
  127. #include "kr_ui.h"
  128. #include "kr_typ.h"
  129.  
  130. #include "ui_inversion.ph"
  131.  
  132.  
  133. /*****************************************************************************
  134.   FUNCTION : ui_inversion
  135.  
  136.   PURPOSE  : Main program for the inversion
  137.   NOTES    : callback from the info panel
  138.   RETURNS  :
  139.   UPDATE   : 29.01.92
  140. ******************************************************************************/
  141.  
  142. void ui_inversion(Widget button, caddr_t call_data)
  143. {
  144.  
  145.     Widget         fbutton,sbutton,stbutton,setbutton,stopbutton,helpbutton;
  146.     Arg           args[10];
  147.     Cardinal       n;
  148.     char           buf[40];
  149.     struct UnitList *IUnit, *OUnit;
  150.     struct Ui_DisplayType *dPtr;
  151.     int maxx,maxy;
  152.     int test;
  153.  
  154.     if (krui_getNoOfUnits() == 0){
  155.     ui_confirmOk("No network loaded !");
  156.     return;
  157.     }
  158.  
  159.  
  160.     if(INVERS_CREATED)
  161.        return;
  162.  
  163.  
  164.     if((test = ui_set_IO_units()) == 1){
  165.       ui_confirmOk("No input and/or output units defined !");
  166.       return;
  167.     }
  168.  
  169.  
  170.     if ((displayPtr = ui_displ_getFreeItem()) == NULL) {
  171.     ui_confirmOk("No more memory for displays available!");
  172.     return;
  173.     }
  174.  
  175.  
  176.     /* now create the widget structure to display input units */
  177.  
  178.     n = 0;
  179.     displayPtr->gridSize = 37;
  180.     dPtr = ui_displ_listPtr;
  181.     while(dPtr != NULL){
  182.        displayPtr->gridSize = dPtr->gridSize;
  183.        dPtr = dPtr->nextPtr;
  184.     }
  185.  
  186.     sprintf(buf,"inversion display");
  187.     ui_InvRootWidget =
  188.     XtCreatePopupShell(buf, topLevelShellWidgetClass, ui_toplevel,args, n);
  189.     displayPtr->frameWidget = 
  190.     XtCreateManagedWidget("form", formWidgetClass, ui_InvRootWidget, NULL, ZERO);
  191.  
  192.     fbutton    = ui_xCreateButtonItem("done", displayPtr->frameWidget, NULL, NULL);
  193.     sbutton    = ui_xCreateButtonItem("multiStep", displayPtr->frameWidget,
  194.                    fbutton, NULL);
  195.     stopbutton = ui_xCreateButtonItem("stop", displayPtr->frameWidget,
  196.                       sbutton, NULL);
  197.     stbutton   = ui_xCreateButtonItem("new", displayPtr->frameWidget,
  198.                    stopbutton, NULL);
  199.     setbutton  = ui_xCreateButtonItem("setup", displayPtr->frameWidget,
  200.                    stbutton, NULL);
  201.     helpbutton  = ui_xCreateButtonItem("help", displayPtr->frameWidget,
  202.                    setbutton, NULL);
  203.  
  204.  
  205.     /* get necessary window size */
  206.  
  207.     maxy = maxx = 0;
  208.     IUnit = inputs;
  209.     do{
  210.       maxy = (IUnit->gridPos.y > maxy)? IUnit->gridPos.y: maxy;
  211.       maxx = (IUnit->gridPos.x > maxx)? IUnit->gridPos.x: maxx;
  212.       IUnit = IUnit->next;
  213.     }while(IUnit != NULL);
  214.     OUnit = outputs;
  215.     do{
  216.       maxy = (OUnit->gridPos.y > maxy)? OUnit->gridPos.y: maxy;
  217.       maxx = (OUnit->gridPos.x > maxx)? OUnit->gridPos.x: maxx;
  218.       OUnit = OUnit->next;
  219.     }while(OUnit != NULL);
  220.     
  221.     n = 0;
  222.     /* XtSetArg(args[n], XtNwidth,  displayPtr->width); n++; */
  223.     /* XtSetArg(args[n], XtNheight, displayPtr->height); n++; */
  224.     XtSetArg(args[n], XtNwidth,    ++maxx * displayPtr->gridSize); n++;
  225.     XtSetArg(args[n], XtNheight,   ++maxy * displayPtr->gridSize); n++;
  226.     XtSetArg(args[n], XtNfromVert, fbutton); n++;
  227.     XtSetArg(args[n], XtNleft,     XtChainLeft); n++;
  228.     XtSetArg(args[n], XtNright,    XtChainRight); n++;
  229.     XtSetArg(args[n], XtNtop,      XtChainTop ); n++;
  230.     XtSetArg(args[n], XtNbottom,   XtChainBottom); n++;
  231.     displayPtr->widget = 
  232.         XtCreateManagedWidget("display",boxWidgetClass,displayPtr->frameWidget,
  233.                   args,n);
  234.  
  235.  
  236.     /* define necessary callbacks */
  237.  
  238.     XtAddCallback(fbutton,   XtNcallback, (XtCallbackProc) ui_closeDisplay,NULL);
  239.     XtAddCallback(sbutton,   XtNcallback, (XtCallbackProc) ui_start_inversion, NULL);
  240.     XtAddCallback(stbutton,  XtNcallback, (XtCallbackProc) ui_invNew, NULL);
  241.     XtAddCallback(stopbutton,  XtNcallback, (XtCallbackProc) ui_stop_inversion, NULL);
  242.     XtAddCallback(setbutton, XtNcallback, (XtCallbackProc) ui_invSetup, NULL);
  243.     XtAddCallback(helpbutton, XtNcallback, (XtCallbackProc) ui_invHelp, (caddr_t) TRUE);
  244.     XtAddEventHandler(displayPtr->widget,StructureNotifyMask | ExposureMask,FALSE, 
  245.               (XtEventHandler) ui_invEvent,inv_display);
  246.     ui_checkWindowPosition(ui_InvRootWidget);
  247.     XtPopup(ui_InvRootWidget, XtGrabNone);
  248.  
  249.     INVERS_CREATED = 1;
  250.     inv_display   = XtDisplay(ui_InvRootWidget);
  251.     inv_screen    = DefaultScreen(inv_display);
  252.     displayPtr->drawable = XtWindow(displayPtr->widget);
  253.     XSelectInput(inv_display, displayPtr->drawable,  ExposureMask);
  254.  
  255.  
  256. }
  257.  
  258.  
  259.  
  260.  
  261. /*****************************************************************************
  262.   FUNCTION : ui_invSetup
  263.  
  264.   PURPOSE  : Display setup panel for Inversion
  265.   NOTES    : 
  266.   RETURNS  :
  267.   UPDATE   : 20.02.92
  268. *****************************************************************************/
  269. static void ui_invSetup(Widget button, caddr_t call_data)
  270. {
  271.     Widget      ui_invBox,doneButton,helpButton;
  272.     Widget      eta_lab,delta_lab,pat_lab,rat_lab;
  273.     Arg         args[5];
  274.     Position    x, y;
  275.     Dimension   width, height;
  276.     Cardinal    n;
  277.     char        buf[40];
  278.  
  279.  
  280.     /* set Popup arguments */
  281.  
  282.     n = 0;
  283.     XtSetArg(args[0], XtNwidth, &width);n++;
  284.     XtSetArg(args[1], XtNheight, &height);n++;
  285.     XtGetValues(button, args, n);
  286.     XtTranslateCoords(button, (Position)(width/2), (Position)(height/2), &x, &y);
  287.     n = 0;
  288.     XtSetArg(args[n], XtNx, x);n++;
  289.     XtSetArg(args[n], XtNy, y);n++;
  290.  
  291.  
  292.     /* Now create Popup */
  293.  
  294.     ui_invpop = XtCreatePopupShell("setup", transientShellWidgetClass, 
  295.                    ui_toplevel, args, n);
  296.     ui_invBox = XtCreateManagedWidget("form", formWidgetClass, ui_invpop, 
  297.                       NULL, ZERO);
  298.     doneButton = ui_xCreateButtonItem("done", ui_invBox, NULL, NULL);
  299.     XtAddCallback(doneButton, XtNcallback, (XtCallbackProc) ui_inv_popupDone, NULL);
  300.     helpButton = ui_xCreateButtonItem("help", ui_invBox, doneButton, NULL);
  301.     XtAddCallback(helpButton, XtNcallback, (XtCallbackProc) ui_invHelp, FALSE);
  302.     eta_lab = ui_xCreateLabelItem("eta           =", ui_invBox,120,
  303.                   NULL,doneButton);
  304.     sprintf(buf,"%g",INV_eta);
  305.     etaW    = ui_xCreateDialogItem("eta_val",ui_invBox,buf,56,eta_lab,doneButton);
  306.     delta_lab = ui_xCreateLabelItem("delta_max     =",ui_invBox,120,
  307.                     NULL,eta_lab);
  308.     sprintf(buf,"%g",INV_delta_max);
  309.     delta_maxW = ui_xCreateDialogItem("delta_max_val",ui_invBox, 
  310.                       buf, 56, delta_lab, etaW);
  311.     pat_lab = ui_xCreateLabelItem("Input pattern =",ui_invBox,120,NULL,delta_lab);
  312.     sprintf(buf,"%g",INPUT_PAT);
  313.     inPatW = ui_xCreateDialogItem("input_pat_val",ui_invBox,buf,56,
  314.                   pat_lab,delta_maxW);
  315.     rat_lab = ui_xCreateLabelItem("2nd approx ratio",ui_invBox,120,NULL,pat_lab);
  316.     sprintf(buf,"%g",RATIO);
  317.     ratioW = ui_xCreateDialogItem("ratio_val",ui_invBox,buf,56,
  318.                   rat_lab,inPatW);
  319.  
  320.  
  321.     /* Display popup now */
  322.  
  323.     ui_checkWindowPosition(ui_invpop);
  324.     XtPopup(ui_invpop, XtGrabExclusive);
  325.     ui_xDontResizeWidget(ui_invpop); 
  326. }
  327.  
  328.  
  329.  
  330.  
  331.  
  332. /*****************************************************************************
  333.   FUNCTION : ui_inv_popupDone
  334.  
  335.   PURPOSE  : read new params and close popup display
  336.   NOTES    : 
  337.   RETURNS  :
  338.   UPDATE   : 20.02.92
  339. *****************************************************************************/
  340. static void ui_inv_popupDone(Widget button, caddr_t call_data)
  341. {
  342.     struct UnitList *IUnit;
  343.  
  344.     INPUT_PAT     = (float)ui_xFloatFromAsciiWidget(inPatW);
  345.     INPUT_PAT     = (INPUT_PAT > 1.0)? 1.0 :INPUT_PAT;
  346.     INPUT_PAT     = (INPUT_PAT < 0.0)? 0.0 :INPUT_PAT;
  347.     INV_eta       = (float)ui_xFloatFromAsciiWidget(etaW);
  348.     INV_delta_max = (float)ui_xFloatFromAsciiWidget(delta_maxW);
  349.     RATIO         = (float)ui_xFloatFromAsciiWidget(ratioW);
  350.     XtDestroyWidget(ui_invpop);
  351.  
  352.     IUnit = inputs;
  353.     while(IUnit != NULL){
  354.       IUnit->act = (FlintType)INPUT_PAT;
  355.       IUnit->i_act = (FlintType)INPUT_PAT;
  356.       if(INPUT_PAT == 1.0)
  357.     IUnit->im_act  = 9.2102404;  
  358.       else if(INPUT_PAT == 0.0)
  359.     IUnit->im_act  = -9.2102404; 
  360.       else
  361.     IUnit->im_act  = (FlintType)(-log((double)(1.0/INPUT_PAT - 1.0))); 
  362.       IUnit = IUnit->next;
  363.     }
  364.     ui_drawInput();
  365. }
  366.  
  367.  
  368.  
  369.  
  370.  
  371. /*****************************************************************************
  372.   FUNCTION : ui_inv_helpDone
  373.  
  374.   PURPOSE  : destroy help window
  375.   NOTES    : 
  376.   RETURNS  :
  377.   UPDATE   : 03.03.92
  378. *****************************************************************************/
  379. static void ui_inv_helpDone(Widget button, caddr_t call_data)
  380. {
  381.     XtDestroyWidget(XtParent(XtParent(button)));
  382. }
  383.  
  384.  
  385.  
  386.  
  387. /*****************************************************************************
  388.   FUNCTION : ui_invHelp
  389.  
  390.   PURPOSE  : display help information for inversion
  391.   NOTES    : 
  392.   RETURNS  :
  393.   UPDATE   : 03.03.92
  394. *****************************************************************************/
  395. static void ui_invHelp(Widget button, Boolean fromMain, caddr_t call_data)
  396. {
  397.     Widget      ui_invHBox,ui_invHelp,doneButton,lab[10];
  398.     Arg         args[5];
  399.     Position    x, y;
  400.     Dimension   width, height;
  401.     Cardinal    n;
  402.     char        buf[80];
  403.  
  404.     /* set Popup arguments */
  405.  
  406.     n = 0;
  407.     XtSetArg(args[0], XtNwidth, &width);n++;
  408.     XtSetArg(args[1], XtNheight, &height);n++;
  409.     XtGetValues(button, args, n);
  410.     XtTranslateCoords(button, (Position)(width), (Position)(height), &x, &y);
  411.     n = 0;
  412.     XtSetArg(args[n], XtNx, x);n++;
  413.     XtSetArg(args[n], XtNy, y+100);n++;
  414.  
  415.  
  416.     /* Now create Popup */
  417.  
  418.     ui_invHelp = XtCreatePopupShell("help", transientShellWidgetClass, 
  419.                    ui_toplevel, args, n);
  420.     ui_invHBox = XtCreateManagedWidget("form", formWidgetClass, ui_invHelp, 
  421.                       NULL, ZERO);
  422.     doneButton = ui_xCreateButtonItem("done", ui_invHBox, NULL, NULL);
  423.     XtAddCallback(doneButton, XtNcallback, (XtCallbackProc) ui_inv_helpDone, NULL);
  424.  
  425.  
  426.     if(fromMain){
  427.        sprintf(buf,"Start/continue inversion with 'STEP'");
  428.        lab[0] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,doneButton);
  429.        sprintf(buf,"Halt inversion run anytime with 'STOP'");
  430.        lab[1] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[0]);
  431.        sprintf(buf,"Reset inversion with 'NEW'");
  432.        lab[2] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[1]);
  433.        sprintf(buf,"Change parameters with 'SETUP'");
  434.        lab[3] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[2]);
  435.        sprintf(buf,"After SETUP continue with 'STEP',");
  436.        lab[4] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[3]);
  437.        sprintf(buf,"  or restart with 'NEW','STEP'");
  438.        lab[5] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[4]);
  439.        sprintf(buf,"HINT: If inversion is performed on an untrained net,");
  440.        lab[6] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[5]);
  441.        sprintf(buf,"      or on a trained net with an average error of more than 0.05,");
  442.        lab[7] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[6]);
  443.        sprintf(buf,"      the algorithm is very likely not to converge !!");
  444.        lab[8] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[7]);
  445.     }else{
  446.        sprintf(buf,"eta           : The learn parameter; should range from 1.0 to 10.0");
  447.        lab[0] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,doneButton);
  448.        sprintf(buf,"delta_max     : The maximum allowed error for a output unit");
  449.        lab[1] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[0]);
  450.        sprintf(buf,"Input  pattern: The initial activation for all input units");
  451.        lab[2] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[1]);
  452.        sprintf(buf,"2nd approx    : The degree to which the target input pattern");
  453.        lab[3] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[2]);
  454.        sprintf(buf,"                is dependent of the initial input pattern");
  455.        lab[4] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[3]);
  456.        sprintf(buf,"                good values range from 0.2 to 0.8");
  457.        lab[5] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[4]);
  458.     }
  459.  
  460.  
  461.     /* Display popup now */
  462.  
  463.     ui_checkWindowPosition(ui_invHelp);
  464.     XtPopup(ui_invHelp, XtGrabExclusive);
  465.     XFlush(ui_display);
  466.  
  467.  
  468. }
  469.  
  470.  
  471.  
  472.  
  473. /*****************************************************************************
  474.   FUNCTION : ui_set_IO_units
  475.  
  476.   PURPOSE  : create a chain of input units and the corresponding pattern
  477.   NOTES    : 
  478.   RETURNS  :
  479.   UPDATE   : 29.01.92
  480. *****************************************************************************/
  481. static int ui_set_IO_units(void)
  482. {
  483.     int            next;
  484.     int            u_type;
  485.     struct PosType position;
  486.     struct UnitList *IUnit,*OUnit,*dummy1,*dummy2;
  487.     int            i_count = 0,
  488.                    o_count = 0,
  489.                    i,
  490.                    max_no;
  491.  
  492.     if((next = krui_getFirstUnit()) == 0)return(0);
  493.  
  494.     IUnit = (struct UnitList *) malloc(sizeof(struct UnitList));
  495.     inputs = IUnit;
  496.     IUnit->prev = NULL;
  497.     OUnit = (struct UnitList *) malloc(sizeof(struct UnitList));
  498.     outputs = OUnit;
  499.     IUnit->prev = NULL;
  500.     max_no = krui_getNoOfUnits();
  501.     for(i=1; i<= max_no; i++){
  502.       u_type = krui_getUnitTType(next);
  503.       if(u_type == INPUT){
  504.      i_count++;
  505.       krui_getUnitPosition(next,&position);
  506.      dummy1 = IUnit;
  507.      IUnit->no      = next;
  508.      IUnit->gridPos = position;
  509.          IUnit->act     = (FlintType)INPUT_PAT;
  510.          IUnit->i_act   = (FlintType)INPUT_PAT;
  511.      if(INPUT_PAT == 1.0)
  512.        IUnit->im_act  = 9.2102404;   /* = -ln(1/0.9999 - 1); */
  513.      else if(INPUT_PAT == 0.0)
  514.        IUnit->im_act  = -9.2102404;  /* = -ln(1/0.0001 - 1); */
  515.      else
  516.        IUnit->im_act  =(FlintType)( -log((double)(1.0/INPUT_PAT - 1.0))); 
  517.      IUnit->next    = (struct UnitList *) malloc(sizeof(struct UnitList));
  518.          IUnit          = IUnit->next;     
  519.      IUnit->prev    = dummy1;
  520.       }else if(u_type == OUTPUT){
  521.      o_count++;
  522.       krui_getUnitPosition(next,&position);
  523.      dummy2         = OUnit;
  524.      OUnit->no      = next;
  525.      OUnit->gridPos = position;
  526.          OUnit->act     = 0.0;
  527.      OUnit->next    = (struct UnitList *) malloc(sizeof(struct UnitList));
  528.          OUnit          = OUnit->next;     
  529.      OUnit->prev    = dummy2;
  530.       }
  531.       next=krui_getNextUnit();
  532.     }
  533.  
  534.     if(i_count == 0 || o_count == 0){
  535.  
  536.       /* Stop inversion if no input or output units are defined */ 
  537.       return(1);
  538.     }else{
  539.  
  540.       /* Finish the pointer chain */
  541.       dummy1->next = NULL;
  542.       dummy2->next = NULL;
  543.       return(0);
  544.     }
  545.  
  546. }
  547.  
  548.  
  549.  
  550.  
  551. /*****************************************************************************
  552.   FUNCTION : ui_closeDisplay
  553.  
  554.   PURPOSE  : closing all widgets for inversion
  555.   NOTES    : 
  556.   RETURNS  :
  557.   UPDATE   : 29.01.92
  558. *****************************************************************************/
  559. static void ui_closeDisplay(Widget w, caddr_t call_data)
  560. {
  561.  
  562.  
  563.     if(INV_RUNNING){
  564.        ui_confirmOk("Stop inversion run before quiting !");
  565.        return;
  566.     }
  567.     XtDestroyWidget(ui_InvRootWidget);
  568.     INVERS_CREATED = 0;
  569.     inputs  = NULL;
  570.     outputs = NULL;
  571. }
  572.  
  573.  
  574. /*****************************************************************************
  575.   FUNCTION : ui_invNew
  576.  
  577.   PURPOSE  : restart the inversion
  578.   NOTES    : 
  579.   RETURNS  :
  580.   UPDATE   : 11.02.92
  581. *****************************************************************************/
  582. static void ui_invNew(Widget w, caddr_t call_data)
  583. {
  584.     struct UnitList *IUnit, *OUnit;
  585.  
  586.     IUnit = inputs;
  587.     while(IUnit != NULL){
  588.       IUnit->act = (FlintType)INPUT_PAT;
  589.       IUnit->i_act = (FlintType)INPUT_PAT;
  590.       if(INPUT_PAT == 1.0)
  591.     IUnit->im_act  = 9.2102404;   /* = -ln(1/0.9999 - 1); */
  592.       else if(INPUT_PAT == 0.0)
  593.     IUnit->im_act  = -9.2102404;  /* = -ln(1/0.0001 - 1); */
  594.       else
  595.     IUnit->im_act  = (FlintType)(-log((double)(1.0/INPUT_PAT - 1.0))); 
  596.       IUnit = IUnit->next;
  597.     }
  598.     OUnit = outputs;
  599.     while(OUnit != NULL){
  600.       OUnit->act = 0.0;
  601.       OUnit->i_act = 0.0;
  602.       OUnit = OUnit->next;
  603.     }
  604.     ui_drawInput();
  605.     INV_NEW = 1;
  606. }
  607.  
  608.  
  609.  
  610.  
  611. /*****************************************************************************
  612.   FUNCTION : ui_invEvent
  613.  
  614.   PURPOSE  : event handler for graphic window
  615.   NOTES    : 
  616.   RETURNS  :
  617.   UPDATE   : 20.02.92
  618. *****************************************************************************/
  619. static void ui_invEvent(Widget w, Display *display, XEvent *event)
  620. {
  621.     switch (event->type){
  622.         case Expose:
  623.                if (event->xexpose.count == 0)
  624.          ui_drawInput();
  625.            break;
  626.     default:
  627.            break;
  628.     }
  629. }
  630.  
  631.  
  632.  
  633.  
  634.  
  635. /*****************************************************************************
  636.   FUNCTION : ui_drawInput
  637.  
  638.   PURPOSE  : drawing the input units
  639.   NOTES    : 
  640.   RETURNS  :
  641.   UPDATE   : 29.01.92
  642. *****************************************************************************/
  643. static void ui_drawInput(void)
  644. {
  645.  
  646.     int            next;
  647.     int            u_type;
  648.     int            dx,dy;
  649.     int            procent_value;
  650.     struct PosType position,pixpos,pixpos2;
  651.     struct UnitList *IUnit, *OUnit;
  652.     
  653.  
  654.  
  655.     /* do nothing if no net is loaded */
  656.  
  657.     if((next = krui_getFirstUnit()) == 0)return;
  658.     
  659.  
  660.     /* prepare window for drawing */
  661.  
  662.     displayPtr->frozen = FALSE;
  663.     XClearWindow(inv_display,displayPtr->drawable);
  664.     if(ui_col_monochromeMode){
  665.        XSetBackground(inv_display,ui_gc,
  666.               ui_backgroundColor);
  667.        XSetForeground(inv_display,
  668.               ui_gc,ui_textColor);
  669.  
  670.        /* draw rectangle for EACH input/output unit */
  671.        do{
  672.          u_type = krui_getUnitTType(next);
  673.          if(u_type == OUTPUT || u_type == INPUT){
  674.          krui_getUnitPosition(next,&position);
  675.             ui_drawGrowingThing(displayPtr, position, -100);
  676.          }
  677.        }while((next=krui_getNextUnit()) != 0);
  678.     }else{
  679.        XSetBackground(inv_display,ui_gc,
  680.            ui_backgroundColor);
  681.        XSetForeground(inv_display,
  682.            ui_gc, ui_editColor[UI_BLACK]);
  683.        XSetFunction(inv_display, ui_gc, GXcopy);
  684.     }
  685.  
  686.  
  687.     /* draw activation of input units */
  688.  
  689.     IUnit = inputs;
  690.     do{
  691.       position.x = displayPtr->gridSize * (IUnit->gridPos.x-displayPtr->origin.x) + 
  692.                displayPtr->gridSize/2;
  693.       position.y = displayPtr->gridSize * (IUnit->gridPos.y-displayPtr->origin.y) + 
  694.                displayPtr->gridSize/2;
  695.       procent_value = (int)(100.0*IUnit->act);
  696.       if(ui_col_monochromeMode){
  697.          pixpos = ui_utilPixUpperLeft(displayPtr,IUnit->gridPos);
  698.          pixpos2 = ui_utilPixLowerRight(displayPtr,IUnit->gridPos,0);
  699.      dx = dy = (int)((float)(pixpos2.x - pixpos.x)*IUnit->act);
  700.      pixpos.x += (int)((float)(pixpos2.x-pixpos.x)*0.5*(1.0 - IUnit->act)+0.5);
  701.      pixpos.y += (int)((float)(pixpos2.y-pixpos.y)*0.5*(1.0 - IUnit->act)+0.5);
  702.      XFillRectangle(inv_display, displayPtr->drawable, ui_gc,
  703.             pixpos.x,pixpos.y,(unsigned int) dx,(unsigned int) dy);
  704.       }else{
  705.          pixpos = ui_utilPixUpperLeft(displayPtr,IUnit->gridPos);
  706.          pixpos2 = ui_utilPixLowerRight(displayPtr,IUnit->gridPos,0);
  707.      XSetForeground(inv_display, ui_gc, 
  708.            ui_col_rangePixels[ui_col_steps+procent_value*ui_col_steps DIV 100]);
  709.      ui_xDeleteRect(inv_display, displayPtr->drawable, ui_gc,pixpos,pixpos2);
  710.       }
  711.       IUnit = IUnit->next;
  712.     }while(IUnit != NULL);
  713.  
  714.  
  715.     /* draw activation of output units */
  716.  
  717.     OUnit = outputs;
  718.     do{
  719.       position.x = displayPtr->gridSize * (OUnit->gridPos.x-displayPtr->origin.x) + 
  720.                displayPtr->gridSize/2;
  721.       position.y = displayPtr->gridSize * (OUnit->gridPos.y-displayPtr->origin.y) + 
  722.                displayPtr->gridSize/2;
  723.  
  724.       procent_value = (int)(100.0*OUnit->act); 
  725.       if(NOT ui_col_monochromeMode){
  726.          pixpos = ui_utilPixUpperLeft(displayPtr,OUnit->gridPos);
  727.          pixpos2 = ui_utilPixLowerRight(displayPtr,OUnit->gridPos,0);
  728.      XSetForeground(inv_display, ui_gc, 
  729.            ui_col_rangePixels[ui_col_steps+procent_value*ui_col_steps DIV 100]);
  730.      ui_xDeleteRect(inv_display, displayPtr->drawable, ui_gc,pixpos,pixpos2);
  731.       }else{ 
  732.          pixpos = ui_utilPixUpperLeft(displayPtr,OUnit->gridPos);
  733.          pixpos2 = ui_utilPixLowerRight(displayPtr,OUnit->gridPos,0);
  734.      dx = dy = (int)((float)(pixpos2.x - pixpos.x)*OUnit->act);
  735.      pixpos.x += (int)((float)(pixpos2.x-pixpos.x)*0.5*(1.0 - OUnit->act)+0.5);
  736.      pixpos.y += (int)((float)(pixpos2.y-pixpos.y)*0.5*(1.0 - OUnit->act)+0.5);
  737.      XFillRectangle(inv_display, displayPtr->drawable, ui_gc,
  738.             pixpos.x,pixpos.y,(unsigned int) dx,(unsigned int) dy);
  739.       }
  740.       OUnit = OUnit->next;
  741.     }while(OUnit != NULL);
  742.  
  743.  
  744.  
  745.     /* drawing finished */
  746.  
  747.     XFlush(inv_display);
  748.     displayPtr->frozen = TRUE;
  749. }
  750.  
  751.  
  752.  
  753.  
  754.  
  755. /*****************************************************************************
  756.   FUNCTION : ui_start_inversion
  757.  
  758.   PURPOSE  : Program to start inversion
  759.   NOTES    : callback from the remote panel
  760.   RETURNS  :
  761.   UPDATE   : 29.01.92
  762. ******************************************************************************/
  763. static void ui_start_inversion(Widget button, caddr_t call_data)
  764. {
  765.     if (ui_workProcId)
  766.         XtRemoveWorkProc(ui_workProcId); /* kill old workProc */
  767.     ui_workType = 99;
  768.     INV_RUNNING = 1;
  769.     ui_workProcId = XtAppAddWorkProc(ui_appContext, (XtWorkProc) ui_do_inversion,NULL); 
  770. }
  771.  
  772.  
  773.  
  774. /*****************************************************************************
  775.   FUNCTION : ui_stop_inversion
  776.  
  777.   PURPOSE  : Program to stop inversion
  778.   NOTES    : callback from the remote panel
  779.   RETURNS  :
  780.   UPDATE   : 29.01.92
  781. ******************************************************************************/
  782. static void ui_stop_inversion(Widget button, caddr_t call_data)
  783. {
  784.     if(ui_workProcId){
  785.       INV_RUNNING = 0;
  786.       ui_drawInput();
  787.       printf("cycle %d inversion error %f, %d error units left\n",
  788.          INV_cycle,INV_error,INV_units);
  789.       XtRemoveWorkProc(ui_workProcId); /* kill old workProc */
  790.       ui_workProcId = (XtWorkProcId) NULL;
  791.     }
  792. }
  793.  
  794.  
  795.  
  796. /*****************************************************************************
  797.   FUNCTION : ui_do_inversion
  798.  
  799.   PURPOSE  : Program for actual inversion algorithm
  800.   NOTES    : callback from the remote panel
  801.   RETURNS  :
  802.   UPDATE   : 29.01.92
  803. ******************************************************************************/
  804.  
  805. static Boolean ui_do_inversion(Widget button, caddr_t call_data)
  806. {
  807.     struct UnitList *OUnit;
  808.     struct SelectionType *SelDummy;
  809.     int dummy;
  810.     double old_err;
  811.     int selUnits, err_units;
  812.     int err;
  813.     static int growing_errors = 0;
  814.  
  815.  
  816.     /* set output pattern */
  817.     
  818.     if(INV_NEW){ 
  819.        INV_cycle = 0;
  820.        selUnits = 0;
  821.        if(krui_getNoOfPatterns() == 0){
  822.       ui_confirmOk("Please load patterns first !");
  823.           INV_RUNNING = 0;
  824.       return(TRUE);
  825.        }
  826.        OUnit = outputs;
  827.        while(OUnit != NULL){
  828.      if((SelDummy = ui_sel_lookForItem(OUnit->no)) != NULL){
  829.        OUnit->i_act = 1.0;
  830.        OUnit->act = 1.0;
  831.        selUnits++;
  832.      }else{
  833.        OUnit->i_act = 0.0;
  834.        OUnit->act = 0.0;
  835.      }
  836.      OUnit = OUnit->next;
  837.        }
  838.        if(!selUnits){
  839.           ui_confirmOk("No target output selected !!");
  840.           INV_RUNNING = 0;
  841.           return(TRUE);
  842.        }
  843.        INV_NEW = 0;  
  844.     }
  845.  
  846.  
  847.     /* do the inversion */
  848.  
  849.     if((err = krui_initInversion()) < 0){
  850.        printf("init returned error %d\n",err);
  851.        INV_RUNNING = 0;
  852.        return(TRUE);
  853.     }
  854.  
  855.     INV_cycle++;
  856.     err_units = 0;
  857.     old_err = INV_error;
  858.     krui_inv_forwardPass(inputs);
  859.     INV_error = krui_inv_backwardPass(INV_eta,INV_delta_max,&err_units,RATIO,
  860.                       inputs,outputs);
  861.     INV_units = err_units;
  862.     if((dummy=(INV_cycle%50)) == 0)
  863.      printf("cycle %d inversion error %f still %d error unit(s)\n",
  864.             INV_cycle,INV_error,INV_units);
  865.     if(old_err<= INV_error)growing_errors++;
  866.     else growing_errors = 0;
  867. /*
  868.     if(growing_errors > 50){
  869.        growing_errors = 0;
  870.        ui_drawInput();
  871.        ui_confirmOk(" Inversion error does not diminish!\n Net might not be properly trained !"); 
  872.        INV_RUNNING = 0;
  873.        return(TRUE);
  874.     }
  875. */
  876.  
  877.     /* check the result of this inversion step */
  878.  
  879.     if(INV_units > 0){
  880.  
  881.        /* while still one unit has an error > delta_max return FALSE,  */
  882.        /* to start another cycle                                       */
  883.        return(FALSE);
  884.     }else{
  885.  
  886.        /*   algorithm has converged, display discovered activation pattern */
  887.        printf("cycle %d inversion error %f, %d error units left\n",
  888.           INV_cycle,INV_error,INV_units);
  889.        ui_drawInput();
  890.        INV_RUNNING = 0;
  891.        return(TRUE);
  892.     }
  893.     
  894.  
  895. }
  896.  
  897. #endif
  898.  
  899.  
  900.